# 类名要满足大驼峰习惯
# class MyTest(object)为新式类 object是所有类的顶级类
class MyTest(object):
    # 魔法方法格式 _xx_
    # def __init__(self):
    #     """初始化对象（创建对象时自动调用）"""
    #     self.name = 'xiaomei'
    # _init_也可以带参数
    age = 12
    def __init__(self, name):
        self.name = name
    def __str__(self):
        """当打印对象时输出的不再是地址而是return的内容"""
        return "这是个测试方法"
    def __del__(self):
        """当删除对象时自动调用"""
        print('对象已删除')
    def test1(self):
        print("test1")
        print(self.name)
        print(self)

class test(MyTest):
    __gender = '男'

    # 获取和修改私有属性 定义类方法
    # 当方法中需要使用类对象(如访问私有类属性等)时，定义类方法类方法一般和类属性配合使用
    # 需要用装饰器@classmethod来标识其为类方法，对于类方法，第一个参数必须是类对象，一般以cls作为第一个参数。
    @classmethod
    def get_gender(cls):
        return cls.__gender


    # 静态方法特点
    # 需要通过装饰器 @staticmethod来进行修饰，静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。
    # 静态方法既可以使用对象访问又可以使用类访问
    # 静态方法使用场景
    # 当方法中既不需要使用实例对象(如实例对象，实例属性)，也不需要使用类对象(如类属性、类方法、创建实例等)时，定义静态方法
    # 取消不需要的参数传递，有利于减少不必要的内存占用和性能消耗

    @staticmethod
    def staticMethon():
        print('这是一个静态方法')

# ob =  MyTest()
ob =  MyTest('xiaomei')
# ob.name = '小鸿'
ob.test1()
print(ob)


# 通过实例对象修改类属性
ob1 = test('hhh')
ob1.age = 11
print(MyTest.age)  # 12
print(ob1.age)  # 11

#返回类内部所有属性和方法对应的字典
print(test.__dict__)
# 返回实例属性和值组成的字典
print(ob1.__dict__)

# 通过类修改类属性
MyTest.age = 22
print(MyTest.age)  # 22
print(ob1.age)  # 11

# 调用类方法
print(ob1.get_gender())

# 调用静态方法
ob1.staticMethon()
test.staticMethon()


# 会发现ob == self
# 由于打印对象和打印self得到的内存地址相同，所以self指的是调用该函数的对象

# 可以创建多个对象
# ob1 = MyTest()
# ob2 = MyTest()
# ob1.test1()
# ob2.test1()
# 可以发现两个对象内存地址不相同

